﻿Imports System.Security.Cryptography
Imports System.Text
Public Class cRSA
    Public Shared Function Encrypt(ByVal Data As String, ByVal Publickey As String) As RSAResult
        Try
            Dim ByteConverter As New UnicodeEncoding()
            Return Encrypt(ByteConverter.GetBytes(Data), Publickey)
        Catch ex As Exception
            Throw New Exception("Encrypt(String): " & ex.Message, ex)
        End Try
    End Function

    Public Shared Function Encrypt(ByVal Data() As Byte, ByVal Publickey As String) As RSAResult
        Try
            Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider()
            RSA.FromXmlString(Publickey)
            Return New RSAResult(RSAEncrypt(Data, RSA.ExportParameters(False), False))
        Catch ex As Exception
            Throw New Exception("Encrypt(Bytes): " & ex.Message, ex)
        End Try
    End Function

    Public Shared Function Decrypt(ByVal Data() As Byte, ByVal Privatekey As String) As RSAResult
        Try
            Dim RSA As System.Security.Cryptography.RSACryptoServiceProvider = New System.Security.Cryptography.RSACryptoServiceProvider()
            RSA.FromXmlString(Privatekey)
            Dim Result As New RSAResult(RSADecrypt(Data, RSA.ExportParameters(True), False))
            Return Result
        Catch ex As Exception
            Throw New Exception("Decrypt(): " & ex.Message, ex)
        End Try
    End Function

    Private Shared Function RSAEncrypt(ByVal DataToEncrypt() As Byte, ByVal RSAKeyInfo As RSAParameters, ByVal DoOAEPPadding As Boolean) As Byte()
        Try
            Dim encryptedData() As Byte
            Using RSA As New RSACryptoServiceProvider
                RSA.ImportParameters(RSAKeyInfo)
                encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding)
            End Using
            Return encryptedData
        Catch e As CryptographicException
            Throw New Exception("RSAEncrypt(): " & e.Message, e)
        End Try
    End Function

    Private Shared Function RSADecrypt(ByVal DataToDecrypt() As Byte, ByVal RSAKeyInfo As RSAParameters, ByVal DoOAEPPadding As Boolean) As Byte()
        Try
            Dim decryptedData() As Byte
            Using RSA As New RSACryptoServiceProvider
                RSA.ImportParameters(RSAKeyInfo)
                decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding)
            End Using
            Return decryptedData
        Catch e As CryptographicException
            Throw New Exception("RSADecrypt(): " & e.Message, e)
        End Try
    End Function

End Class

Public Class Keypair
    Private _Publickey As String = String.Empty
    Private _Privatekey As String = String.Empty
    Public Property Publickey() As String
        Get
            Return _Publickey
        End Get
        Set(ByVal value As String)
            _Publickey = value
        End Set
    End Property
    Public Property Privatekey() As String
        Get
            Return _Privatekey
        End Get
        Set(ByVal value As String)
            _Privatekey = value
        End Set
    End Property
    Public Shared Function CreateNewKeys() As Keypair
        Try
            Using RSA As New RSACryptoServiceProvider
                Dim Keys As New Keypair
                keys.Privatekey = RSA.ToXmlString(True)
                Keys.Publickey = RSA.ToXmlString(False)
                Return Keys
            End Using
        Catch ex As Exception
            Throw New Exception("Keypair.CreateNewKeys():" & ex.Message, ex)
        End Try
    End Function
End Class

Public Class RSAResult
    Private _Data() As Byte
    Public Sub New(ByVal Data() As Byte)
        _Data = Data
    End Sub
    Public ReadOnly Property AsBytes() As Byte()
        Get
            Return _Data
        End Get
    End Property
    Public ReadOnly Property AsString() As String
        Get
            Dim ByteConverter As New UnicodeEncoding()
            Return ByteConverter.GetString(_Data)
        End Get
    End Property
    Public ReadOnly Property AsBase64String() As String
        Get
            Return Convert.ToBase64String(_Data)
        End Get
    End Property
End Class